package org.cybzacg.convert.converters.date;

import lombok.extern.slf4j.Slf4j;
import org.cybzacg.convert.annotation.Converter;
import org.cybzacg.convert.context.ConversionContext;
import org.cybzacg.convert.enums.ConversionPriority;
import org.cybzacg.convert.enums.ConversionType;

import java.time.Duration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Duration转换器
 * 专门处理Duration类型的转换
 *
 * @author cybzacg.blog
 * @version 4.0
 * @since 3.0
 */
@Slf4j
@Converter(name = "DurationConverter", priority = ConversionPriority.MEDIUM_HIGH, description = "Duration类型转换器，处理各种类型到java.time.Duration的转换", version = "4.0", author = "cybzacg.blog", supportedTypes = {
        Duration.class }, tags = { "duration", "time", "conversion" })
public class DurationConverter extends AbstractIntervalConverter<Duration> {

    // 时间单位模式
    private static final Pattern TIME_PATTERN = Pattern.compile("(\\d+)([smhd])");

    public DurationConverter() {
        super(ConversionPriority.MEDIUM_HIGH);
    }

    @Override
    protected ConversionType getConversionType() {
        return ConversionType.DURATION;
    }

    @Override
    protected Duration convertFromNumber(Number source, ConversionContext context) {
        return Duration.ofMillis(source.longValue());
    }

    @Override
    protected Duration parseIsoFormat(String str) {
        return Duration.parse(str);
    }

    @Override
    protected Duration parseChineseFormat(String str) {
        long hours = 0, minutes = 0, seconds = 0, millis = 0;

        // 提取小时
        if (str.contains("小时") || str.contains("时")) {
            String hourStr = extractChineseNumber(str, "小时", "时");
            if (!hourStr.isEmpty()) {
                hours = Long.parseLong(hourStr);
            }
        }

        // 提取分钟
        if (str.contains("分钟") || str.contains("分")) {
            String minuteStr = extractChineseNumber(str, "分钟", "分");
            if (!minuteStr.isEmpty()) {
                minutes = Long.parseLong(minuteStr);
            }
        }

        // 提取秒
        if (str.contains("秒")) {
            String secondStr = extractChineseNumber(str, "秒");
            if (!secondStr.isEmpty()) {
                seconds = Long.parseLong(secondStr);
            }
        }

        // 提取毫秒
        if (str.contains("毫秒")) {
            String milliStr = extractChineseNumber(str, "毫秒");
            if (!milliStr.isEmpty()) {
                millis = Long.parseLong(milliStr);
            }
        }

        return Duration.ofHours(hours).plusMinutes(minutes).plusSeconds(seconds).plusMillis(millis);
    }

    @Override
    protected Duration parseSimpleFormat(String str) {
        // 尝试简单时间格式 (如: "30s", "5m", "2h", "1d")
        if (str.matches(".*[smhd].*")) {
            Matcher matcher = TIME_PATTERN.matcher(str);
            Duration result = Duration.ZERO;

            while (matcher.find()) {
                long value = Long.parseLong(matcher.group(1));
                String unit = matcher.group(2);

                result = switch (unit) {
                    case "s" -> result.plusSeconds(value);
                    case "m" -> result.plusMinutes(value);
                    case "h" -> result.plusHours(value);
                    case "d" -> result.plusDays(value);
                    default -> result;
                };
            }
            return result;
        }

        // 尝试冒号分隔格式 (HH:mm:ss 或 mm:ss)
        if (str.contains(":")) {
            return parseColonDuration(str);
        }

        return null;
    }

    @Override
    protected Duration parseNumericString(String str) {
        long milliseconds = Long.parseLong(str);
        return Duration.ofMillis(milliseconds);
    }

    @Override
    protected boolean containsChineseUnits(String str) {
        return str.contains("时") || str.contains("分") || str.contains("秒") ||
                str.contains("小时") || str.contains("分钟") || str.contains("毫秒");
    }

    @Override
    protected boolean isIntervalType(Object obj) {
        return obj instanceof Duration;
    }

    @Override
    protected Duration castToInterval(Object obj) {
        return (Duration) obj;
    }

    @Override
    protected Duration getDefaultValue() {
        return org.cybzacg.convert.constants.DateTimeDefaults.DURATION_DEFAULT;
    }

    @Override
    protected String getIntervalTypeName() {
        return "Duration";
    }

    /**
     * 解析冒号分隔格式 (HH:mm:ss 或 mm:ss)
     */
    private Duration parseColonDuration(String str) {
        String[] parts = str.split(":");

        if (parts.length == 2) {
            // 格式: mm:ss
            long minutes = Long.parseLong(parts[0].trim());
            long seconds = Long.parseLong(parts[1].trim());
            return Duration.ofMinutes(minutes).plusSeconds(seconds);
        } else if (parts.length == 3) {
            // 格式: HH:mm:ss
            long hours = Long.parseLong(parts[0].trim());
            long minutes = Long.parseLong(parts[1].trim());
            long seconds = Long.parseLong(parts[2].trim());
            return Duration.ofHours(hours).plusMinutes(minutes).plusSeconds(seconds);
        } else if (parts.length == 4) {
            // 格式: HH:mm:ss.SSS
            long hours = Long.parseLong(parts[0].trim());
            long minutes = Long.parseLong(parts[1].trim());
            long seconds = Long.parseLong(parts[2].trim());
            long millis = Long.parseLong(parts[3].trim());
            return Duration.ofHours(hours).plusMinutes(minutes).plusSeconds(seconds).plusMillis(millis);
        }

        throw new IllegalArgumentException("不支持的时间格式: " + str);
    }

    @Override
    public boolean supports(Class<?> targetType) {
        return targetType == Duration.class;
    }

    @Override
    public Class<?> getSupportedType() {
        return Duration.class;
    }

    @Override
    public String getName() {
        return "DurationConverter";
    }
}
